<template>
  <div class="ai-image-page">
    <div class="page-header card-frost">
      <div class="titles">
        <h1><span class="ink-accent">AI</span>绘图工坊</h1>
        <p class="subtitle">以文字召唤古意图景 · 融合传统风格与智能生成</p>
      </div>
      <div class="header-actions" :class="{ dim: store.generating }">
        <el-button class="btn-gradient pulse-btn" size="large" :disabled="!store.prompt || store.generating" :loading="store.generating" @click="store.generateImage()">
          {{ store.generating ? '生成中…' : '生成图像' }}
        </el-button>
        <el-button v-if="store.linkContext.returnUrl" size="large" text type="primary" @click="goBack" style="margin-left:12px">返回原文</el-button>
      </div>
    </div>

    <div v-if="store.hasLinkContext" class="excerpt-banner">
      <div class="excerpt-inner">
        <div class="ctx-line">来源：第 {{ store.linkContext.chapter }} 章 · 第 {{ store.linkContext.paragraph }} 段</div>
        <pre class="excerpt-text">{{ store.linkContext.excerpt }}</pre>
        <div class="banner-actions">
          <el-button size="small" text type="info" @click="resetPrompt" :disabled="!store.promptEdited">重置提示词</el-button>
        </div>
      </div>
    </div>

    <div class="main-surface">
    <el-row :gutter="24" class="main-grid">
      <el-col :xs="24" :md="10" class="left-panel">
        <el-card shadow="hover" class="panel">
          <template #header>
            <div class="panel-header">
              <span>提示词 & 风格</span>
              <el-button size="small" text type="info" @click="resetPrompt" :disabled="!store.basePromptSnapshot || !store.promptEdited">恢复初始</el-button>
            </div>
          </template>
          <el-form label-width="60px" class="prompt-form">
            <el-form-item label="描述">
              <el-input
                v-model="store.prompt"
                type="textarea"
                :autosize="{minRows:6,maxRows:10}"
                placeholder="描述你想生成的画面（例如：‘群山云海间，一只仙鹤掠过清晨雾色’）"
              />
            </el-form-item>
            <el-form-item label="风格">
              <div class="style-picker">
                <el-tooltip v-for="s in store.stylePresets" :key="s.key" :content="s.desc" placement="top" transition="none">
                  <el-tag
                    :class="['style-tag', { active: s.key === store.style }]"
                    :type="s.key === store.style ? 'success' : 'info'"
                    @click="store.setStyle(s.key)"
                  >{{ s.label }}</el-tag>
                </el-tooltip>
              </div>
            </el-form-item>
            <el-form-item label="尺寸">
              <el-input v-model="store.sizeFixed" size="small" disabled style="width:140px" />
              <span class="hint">（暂仅支持 1024×1024）</span>
            </el-form-item>
          </el-form>
        </el-card>

        <el-card shadow="never" class="panel secondary">
          <template #header><span>会话内最新生成</span></template>
          <div v-if="!store.sessionImages.length" class="empty-block">尚未生成图像</div>
          <el-row :gutter="8">
            <el-col :span="12" v-for="img in store.sessionImages" :key="img.id" class="img-cell">
              <el-card body-class="img-card-body" shadow="never">
                <div class="img-wrap" @click="preview(img)">
                  <img :src="resolve(img.image_url)" :alt="img.prompt" loading="lazy" />
                </div>
                <div class="meta-line">
                  <el-tag size="small" type="info">{{ mapStyleLabel(img.style) }}</el-tag>
                  <el-button size="small" text type="primary" @click.stop="reuse(img)">再用</el-button>
                </div>
              </el-card>
            </el-col>
          </el-row>
        </el-card>
      </el-col>

      <el-col :xs="24" :md="14" class="right-panel">
        <el-card shadow="hover" class="panel stats-panel">
          <template #header>
            <div class="panel-header">
              <span>历史记录</span>
              <div class="panel-actions">
                <el-button
                  size="small"
                  :class="['hist-action-btn', { gradient: store.history.items.length > 6 && !historyExpanded, disabled: store.history.items.length <= 6 }]"
                  :disabled="store.history.items.length <= 6"
                  @click="toggleHistory"
                >{{ historyExpanded ? '收起' : '更多' }}</el-button>
                <el-button
                  size="small"
                  :class="['hist-action-btn', { active: store.history.favoritesOnly }]"
                  @click="toggleFavorites"
                >{{ store.history.favoritesOnly ? '仅收藏' : '全部' }}</el-button>
                <el-button size="small" class="hist-action-btn" @click="reloadHistory(true)">刷新</el-button>
              </div>
            </div>
          </template>
          <div class="stats-bar" v-if="statsComputed">
            <div class="stat-chip">
              <label>总生成</label>
              <span>{{ statsComputed.total }}</span>
            </div>
            <div class="stat-chip">
              <label>收藏</label>
              <span>{{ statsComputed.favorites }}</span>
            </div>
            <div class="stat-chip" v-for="st in statsComputed.styles.slice(0,3)" :key="st.style">
              <label>{{ st.style }}</label>
              <span>{{ st.count }}</span>
            </div>
            <div class="stat-chip more" v-if="statsComputed.styles.length > 3">
              +{{ statsComputed.styles.length - 3 }} 更多
            </div>
          </div>
          <div class="history-list" :class="{ expanded: historyExpanded }" v-loading="store.history.loading || historyLoadingAll">
            <div v-if="!store.history.items.length && !store.history.loading" class="empty-block">暂无历史记录</div>
            <el-row :gutter="10">
              <el-col :span="8" v-for="h in displayHistoryItems" :key="h.id" class="hist-cell">
                <div class="hist-item">
                  <div class="thumb" @click="preview(h)">
                    <img :src="resolve(h.image_url)" :alt="h.prompt" loading="lazy" />
                  </div>
                  <div class="actions">
                    <el-tooltip content="收藏/取消">
                      <el-button :type="h.is_favorite ? 'warning' : 'info'" size="small" circle icon="Star" @click.stop="toggleFav(h)" />
                    </el-tooltip>
                    <el-tooltip content="再生成">
                      <el-button size="small" circle icon="Refresh" @click.stop="reuse(h)" />
                    </el-tooltip>
                    <el-tooltip content="删除">
                      <el-button size="small" type="danger" circle icon="Delete" @click.stop="remove(h)" />
                    </el-tooltip>
                  </div>
                </div>
              </el-col>
            </el-row>
            <div v-if="historyExpanded && !store.history.endReached && !historyLoadingAll" class="load-more-inline">
              <el-button size="small" @click="loadMore">加载更多</el-button>
            </div>
            <div v-if="historyLoadingAll" class="loading-all-hint">正在加载全部…</div>
          </div>
        </el-card>
      </el-col>
  </el-row>
  </div>

    <el-dialog
      v-model="previewVisible"
      :width="previewDialogWidth"
      top="5vh"
      :close-on-click-modal="false"
      class="image-preview-dialog"
    >
      <template #header>图像预览</template>
      <div v-if="currentImage" class="preview-body">
        <div class="preview-img-wrap">
          <img :src="resolve(currentImage.image_url)" class="preview-img" />
        </div>
        <div class="preview-meta">
          <p class="prompt">{{ currentImage.prompt }}</p>
          <el-tag size="small" type="info">{{ mapStyleLabel(currentImage.style) }}</el-tag>
          <div class="op-btns">
            <el-button class="op-btn secondary" size="small" @click="reuse(currentImage)">再使用提示词</el-button>
            <el-button class="op-btn primary" size="small" type="primary" @click="download(currentImage)">下载</el-button>
            <el-button
              v-if="currentImage"
              class="op-btn accent"
              size="small"
              type="success"
              @click="setAsAvatar(currentImage)"
            >设为头像</el-button>
          </div>
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script setup>
import { onMounted, ref, computed, watch, onBeforeUnmount } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { useAiImageStore } from '@/store/aiImage/useAiImageStore'
import { ElMessage } from 'element-plus'
import api from '@/api/http'

const store = useAiImageStore()
const route = useRoute()
const router = useRouter()

// 初始化（M3：解析路由参数）
onMounted(() => {
  store.initFromRoute(route.query || {}, { force: true })
  store.loadHistory({ reset: true })
  store.loadStats()
})

// 监听路由参数变化（在同一页面内再次从阅读页跳转过来）
watch(() => route.fullPath, () => {
  store.initFromRoute(route.query || {}, { force: true })
})

function goBack() {
  if (store.linkContext.returnUrl) {
    // 兼容编码
    try { router.push(store.linkContext.returnUrl) } catch { router.back() }
  } else { router.back() }
}

// 方法
const resetPrompt = () => store.resetPromptToDerived()
const reuse = (img) => { store.reuseFromHistory(img); ElMessage.success('已填入提示词') }
const toggleFav = (img) => store.toggleFavorite(img)
const remove = async (img) => { await store.deleteImage(img); ElMessage.success('已删除') }
const loadMore = () => store.loadHistory()
const reloadHistory = (force) => store.loadHistory({ reset: true })

// 预览
const previewVisible = ref(false)
const currentImage = ref(null)
const preview = (img) => { currentImage.value = img; previewVisible.value = true }

// 预览弹窗宽度随视口自适应，避免窄屏溢出
const previewDialogWidth = ref('720px')
const updatePreviewWidth = () => {
  const vw = window.innerWidth || document.documentElement.clientWidth || 0
  if (vw <= 480) previewDialogWidth.value = '96%'
  else if (vw <= 768) previewDialogWidth.value = '92%'
  else if (vw <= 1024) previewDialogWidth.value = '80%'
  else previewDialogWidth.value = '720px'
}
onMounted(() => {
  updatePreviewWidth()
  window.addEventListener('resize', updatePreviewWidth, { passive: true })
})
onBeforeUnmount(() => {
  window.removeEventListener('resize', updatePreviewWidth)
})

// URL 解析（临时与 ApiTest 保持简单）
const resolve = (url) => {
  if (!url) return ''
  if (url.startsWith('http')) return url
  const origin = window.location.origin
  return url.startsWith('/') ? origin + url : origin + '/static/' + url
}

const mapStyleLabel = (k) => {
  const found = store.stylePresets.find(s => s.key === k || s.label === k)
  return found ? found.label : k
}

const showLoadMore = computed(() => store.history.items.length > 0) // 保留（未使用但可能将来用）
const statsComputed = computed(() => {
  if (!store.stats) return null
  const styles = [...(store.stats.style_stats || [])].sort((a,b)=>b.count-a.count)
  return { total: store.stats.total_images, favorites: store.stats.favorite_images, styles }
})

watch(() => store.history.favoritesOnly, () => { store.loadHistory({ reset: true }) })

// 下载（简单版）
const download = async (img) => {
  try {
    const link = document.createElement('a')
    link.href = resolve(img.image_url) + '?dl=1'
    link.download = 'image_' + Date.now() + '.jpg'
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
  } catch {}
}

// 设为头像：复用个人中心的 URL 设置逻辑
const setAsAvatar = async (img) => {
  if (!img) return
  const url = resolve(img.image_url)
  try {
    const response = await api.put('/api/auth/avatar/url', { avatar_url: url })
    console.log('✅ 设为头像成功', response)
    ElMessage.success('已将此图像设为头像')
    // 可选：后续如果需要同步顶部头像，可在这里派发事件
    // window.dispatchEvent(new CustomEvent('avatar-updated', { detail: response.data }))
  } catch (err) {
    console.error('❌ 设为头像出错:', err)
    console.error('响应状态:', err?.response?.status)
    console.error('响应数据:', err?.response?.data)
    console.error('请求地址:', err?.config?.url)
    ElMessage.error(err?.response?.data?.detail || '设置头像失败')
  }
}

// --- 新的历史记录折叠/展开逻辑 ---
const historyExpanded = ref(false)
const historyLoadingAll = ref(false)
const displayHistoryItems = computed(() => {
  if (!historyExpanded.value) return store.history.items.slice(0, 6)
  return store.history.items
})
async function toggleHistory() {
  if (!historyExpanded.value) {
    historyExpanded.value = true
    // 展开后若尚未加载完则自动加载全部
    if (!store.history.endReached) {
      historyLoadingAll.value = true
      // 逐页加载直到 endReached 或达到一个上限（防止极端数据量）
      let safety = 20
      while (!store.history.endReached && safety-- > 0) {
        await store.loadHistory()
      }
      historyLoadingAll.value = false
    }
  } else {
    historyExpanded.value = false
  }
}
function toggleFavorites() {
  store.history.favoritesOnly = !store.history.favoritesOnly
}
</script>

<style scoped>
.ai-image-page { padding:24px clamp(16px,2vw,40px) 60px; background:linear-gradient(140deg,#eef1f3 0%,#f2f1ed 40%,#ece9e1 100%); min-height:100vh; }
.page-header { display:flex; justify-content:space-between; align-items:flex-end; flex-wrap:wrap; margin-bottom:20px; padding:18px 22px; border-radius:14px; position:relative; overflow:hidden; }
.page-header::before { content:''; position:absolute; inset:0; background:linear-gradient(120deg,rgba(255,255,255,0.75),rgba(255,255,255,0.35)); backdrop-filter:blur(6px); }
.page-header .titles, .page-header .header-actions { position:relative; z-index:1; }
.titles h1 { font-size:30px; margin:0; letter-spacing:1px; font-weight:600; }
.ink-accent { background:linear-gradient(90deg,#7d4f21,#c89b4a); -webkit-background-clip:text; background-clip:text; color:transparent; }
.titles .subtitle { margin:6px 0 0; font-size:13px; color:#5e5e55; }
.header-actions.dim { opacity:0.85; }
.pulse-btn { transition:box-shadow 0.3s; }
.pulse-btn:hover { box-shadow:0 4px 14px rgba(160,120,60,0.35); }
.panel { margin-bottom:20px; border-radius:16px; overflow:hidden; }
.panel.secondary { margin-top:12px; }
.main-surface { backdrop-filter:blur(4px); background:rgba(255,255,255,0.82); border:1px solid #e5e1d9; border-radius:28px; padding:32px clamp(20px,2.2vw,46px) 44px; max-width:1680px; margin:0 auto; box-shadow:0 8px 32px -8px rgba(0,0,0,0.08), 0 2px 6px rgba(0,0,0,0.05); }
.btn-gradient { background:linear-gradient(90deg,#bb8a34,#d8b567,#e2c884); color:#fff; border:none; font-weight:600; letter-spacing:.5px; padding:14px 34px; border-radius:999px; box-shadow:0 4px 14px -4px rgba(180,140,60,0.55); }
.btn-gradient:hover { filter:brightness(1.05); box-shadow:0 6px 20px -6px rgba(180,140,60,0.6); }
.btn-gradient:disabled { opacity:.55; box-shadow:none; }
.btn-gradient.is-loading { cursor:progress; }
.panel-header { display:flex; justify-content:space-between; align-items:center; font-weight:600; }
.prompt-form { margin-top:4px; }
.style-picker { display:flex; flex-wrap:wrap; gap:8px; }
.style-tag { cursor:pointer; user-select:none; transition:transform .18s, box-shadow .25s; border-radius:20px; }
.style-tag.active { transform:translateY(-2px); box-shadow:0 3px 10px rgba(0,0,0,0.12); }
.style-tag:hover { transform:translateY(-1px); }
.hint { font-size:12px; color:#888; margin-left:8px; }
.img-cell { margin-bottom:10px; }
.img-wrap { position:relative; padding-top:100%; overflow:hidden; border-radius:10px; background:linear-gradient(135deg,#f0ede7,#e0dbd2); border:1px solid #ddd; }
.img-wrap img { position:absolute; top:0; left:0; width:100%; height:100%; object-fit:cover; transition:transform .35s ease; }
.img-wrap:hover img { transform:scale(1.05); }
.meta-line { display:flex; justify-content:space-between; align-items:center; margin-top:4px; }
.history-list { min-height:320px; }
.hist-item { position:relative; margin-bottom:10px; }
.hist-item .thumb { position:relative; padding-top:100%; background:linear-gradient(135deg,#f2f1ed,#e6e1d9); border:1px solid #ddd; border-radius:10px; overflow:hidden; cursor:pointer; }
.hist-item img { position:absolute; top:0; left:0; width:100%; height:100%; object-fit:cover; }
.hist-item .actions { display:flex; justify-content:space-between; margin-top:4px; }
.empty-block { padding:40px 0; text-align:center; color:#9a9488; font-size:13px; letter-spacing:0.5px; }
.load-more { text-align:center; margin-top:10px; }
.hist-action-btn { background:transparent; border:1px solid #c9c1b5; color:#5d5142; padding:4px 12px; border-radius:16px; line-height:1; font-size:12px; transition:.25s; }
.hist-action-btn:hover:not(.disabled) { background:#f3efe9; }
.hist-action-btn.gradient { background:linear-gradient(90deg,#bb8a34,#d8b567,#e2c884); color:#fff; border:none; box-shadow:0 2px 8px -2px rgba(180,140,60,.4); }
.hist-action-btn.gradient:hover { filter:brightness(1.05); }
.hist-action-btn.disabled { opacity:.45; cursor:default; }
.hist-action-btn.active { background:#ece3d4; border-color:#b59a72; color:#6a4d1d; font-weight:600; }
.history-list { position:relative; }
.history-list.expanded { max-height:480px; overflow-y:auto; padding-right:4px; }
.history-list.expanded::-webkit-scrollbar { width:8px; }
.history-list.expanded::-webkit-scrollbar-thumb { background:#c9b89f; border-radius:4px; }
.load-more-inline { text-align:center; margin:12px 0 6px; }
.loading-all-hint { text-align:center; font-size:12px; color:#8a7b68; padding:8px 0; }
.preview-body { display:flex; flex-direction:column; gap:14px; }
.preview-img-wrap { width:100%; max-height:70vh; overflow:hidden; border-radius:14px; background:#111; display:flex; align-items:center; justify-content:center; }
.preview-img { max-width:100%; max-height:70vh; object-fit:contain; border-radius:10px; box-shadow:0 8px 26px rgba(0,0,0,0.45); }
.preview-meta { font-size:13px; color:#444; display:flex; flex-direction:column; gap:8px; }
.preview-meta .prompt { white-space:pre-wrap; word-break:break-word; padding:10px 12px; background:linear-gradient(135deg,#fbfbfa,#f0eee9); border-radius:8px; border:1px solid #e3e1dc; }
.stats-bar { display:flex; flex-wrap:wrap; gap:10px; margin-bottom:14px; }
.stat-chip { background:linear-gradient(135deg,#faf9f6,#ece8df); padding:8px 14px; border-radius:10px; font-size:12px; display:flex; flex-direction:column; box-shadow:0 2px 6px rgba(0,0,0,0.05); min-width:80px; }
.stat-chip label { font-size:11px; color:#7b7368; letter-spacing:1px; }
.stat-chip span { font-weight:600; color:#5a4a32; font-size:15px; }
.stat-chip.more { justify-content:center; align-items:center; font-size:12px; cursor:default; }
.stats-panel { position:relative; }
.op-btns { margin-top:4px; display:flex; flex-wrap:wrap; gap:8px; }
.op-btns .op-btn { border-radius:999px; padding:6px 14px; font-size:12px; }
.op-btns .op-btn.secondary { border-color:#d1d5db; color:#4b5563; }
.op-btns .op-btn.primary { background:linear-gradient(120deg,#2563eb,#4f46e5); border:none; }
.op-btns .op-btn.accent { background:linear-gradient(120deg,#16a34a,#22c55e); border:none; }
.op-btns .op-btn.primary:hover,
.op-btns .op-btn.accent:hover { filter:brightness(1.05); }
.excerpt-banner { margin:0 0 20px; }
.excerpt-inner { background:linear-gradient(120deg,#fffefb,#f4efe6); border:1px solid #e2d9cc; padding:14px 18px 12px; border-radius:18px; position:relative; box-shadow:0 4px 18px -6px rgba(0,0,0,0.06); }
.excerpt-inner .ctx-line { font-size:12px; color:#7a6a55; letter-spacing:1px; margin-bottom:4px; }
.excerpt-text { margin:0; font-size:13px; line-height:1.6; white-space:pre-wrap; font-family:inherit; color:#4a3f31; background:transparent; }
.banner-actions { position:absolute; top:8px; right:10px; }
@media (min-width: 900px) {
  .main-grid { align-items:stretch; }
  .left-panel { display:flex; flex-direction:column; }
  .right-panel { display:flex; flex-direction:column; }
}

@media (max-width: 600px) {
  .preview-img-wrap { max-height:60vh; }
  .preview-img { max-height:60vh; }
}
</style>